﻿using SCG.General;
using System;
using System.Net;

namespace SCG.SolarVengeanceEngine.StarShips
{
    //Tug
    public class Tug : StarShip
    {
        //constructor
        public Tug(SVGame game, Player owner, int engines, StarSystem origin)
            : base(game, owner, engines, 0, origin)
        {
        }

        //StarShip Name
        public override string Name
        {
            get
            {
                return "Tug";
            }
        }

        //description
        public override string Description
        {
            get
            {
                return "A Tug can tow a single StarShip, either friendly or enemy.  The towed StarShip will move along next to the Tug as the Tug moves.  StarShips that are being towed cannot move on their own, or execute any other orders.  The Tug can release a towed StarShip at any time.";
            }
        }

        //ship type
        public override StarShipType ShipType
        {
            get
            {
                return StarShipType.Tug;
            }
        }

        //The StarShip that this ship is towing
        public StarShip Towing
        {
            get
            {
                return _towing;
            }
            set
            {
                _towing = value;
                if (_towing != null)
                    _towing.ProhibitMove = true;
                Game.SubmitStateChange(StateChange.Towing, this, value);

                //If they're towing a GravShip the GravShip releases its target
                if (Towing != null && Towing.ShipType == StarShipType.GravShip)
                {
                    GravShip grav = Towing as GravShip;
                    if (grav.Dragging != null)
                        grav.Dragging = null;
                }
            }
        }

        //can execute the target starship order
        public override bool CanExecuteOrder(OrderType ot)
        {
            switch (ot)
            {
                case OrderType.TargetStarShip:
                    return true;
                case OrderType.TugRelease:
                    return Towing != null;
                default:
                    return base.CanExecuteOrder(ot);
            }
        }

        //can target any visible starship
        public override bool CanTargetStarShip(StarShip ship, bool respectAlliance)
        {
            return ship.VisibleTo[Owner] && ship != this;
        }

        //Prohibit StarShips being towed from performing actions
        protected internal override void CommonPreProcessing()
        {
            if (Towing != null)
            {
                Towing.ProhibitMove = true;
                Towing.ProhibitAction = true;
            }
        }

        //clear the towed ship if its destroyed
        protected internal override void CommonPostProcessing()
        {
            if (Towing != null)
                if (Towing.Destroyed)
                    Towing = null;

            //also clear it if the target ship isnt adjacent - this might mean one or both was moved
            if (Towing != null)
                if (!IsAdjacent(Towing))
                    Towing = null;
        }

        //clear the towed ship after traveling through a wormhole
        protected internal override void WormholeTraveled()
        {
            Towing = null;
        }

        //Move the towed ship along with the tug
        protected internal override void PostMove(int oldX, int oldY)
        {
            if (Towing != null)
                Game.MoveShipTowardPoint(Towing, new SCGPoint(oldX, oldY), EffectiveEngines);
        }

        //account for this tug being tugged by another tug
        public override int EffectiveEngines
        {
            get
            {
                if (ProhibitMove)
                {
                    //we might be getting towed, see if we are
                    foreach(StarShip ship in Game.StarShips)
                        if (ship.ShipType == StarShipType.Tug)
                        {
                            Tug otherTug = ship as Tug;
                            if (otherTug.Towing == this)
                            {
                                //that's the one!
                                return otherTug.EffectiveEngines;
                            }
                        }
                }
                return base.EffectiveEngines;
            }
        }

        //start towing a starship
        protected override void TargetAdjacentStarShip(StarShip target)
        {
            Towing = target;          
            Order = null;
        }

        //persistence
        protected override string SubClassPersist()
        {
            Tokenizer tok = new Tokenizer();
            tok.AppendToken(Towing != null);
            if (Towing != null)
                tok.AppendToken(Towing.Code);
            return base.SubClassPersist() + tok.Result;
        }
        protected override void SubClassParse(SVTokenizer tok)
        {
            base.SubClassParse(tok);
            if (tok.TokenBoolean)
                _code = tok.TokenString;
        }
        public override void Relink()
        {
            if (_code != "")
                Towing = Game.FindStarShip(_code);
        }

        //private members
        private string _code = "";
        private StarShip _towing = null;
    }
}
